<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script type="text/javascript">
            //http://www.ibiblio.org/e-notes/Splines/None.htm
            
            /**Computes factorial*/
            function fact(k){
                if(k==0 || k==1){
                    return 1;
                }
                else{
                    return k * fact(k-1);
                }
            }
            
            /**Computes Bernstain*/
            function B(i,n,u){
                //if(n < i) throw "Wrong";
                return fact(n) / (fact(i) * fact(n-i))* Math.pow(u, i) * Math.pow(1-u, n-i);
            }
            
            var points = [[100, 100], [200, 100], [200, 200], [300, 200], [300, 100]];
             var s2_6 = [[100, 50], [80, 50], [80, 150], [180, 150], [180, 130], [160, 130] , [160, 30] /*,  [200, 10]*/];
             
//            function P(u, points){
//                var r = [0,0];
//                var n = points.length-1;
//                for(var i=0; i <= n; i++){
//                    r[0] += points[i][0] * B(i, n, u);
//                    r[1] += points[i][1] * B(i, n, u);
//                }                
//                return r;
//            }
            
            function sample(P){
                
                var sol = [];
                var n = P.length;
                /**I do not get why first 4 must be 0 and last 3 of same value.....but otherwise we will get division by zero*/
                var k = [0,0,0];                
                
                for(j=0;j<=n-3;j++){
                    k.push(j);
                }
                
                k.push(n-3, n-3);
                alert(k);
                
//                var k = [];
//                for(j=0;j<=n+3;j++){
//                    k.push(j);
//                }
                
//                P.unshift( [P[0][0], P[0][1]] );
//                P.push( [P[P.length-1][0], P[P.length-1][1]] );
//                var k = [];
//                for(j=0;j<=n+3;j++){
//                    k.push(j * 0.01);
//                }
                
                
                for(i=1; i<=n-3; i++){
                    //q1
                    var q1 = divide( sum( multiply(P[i], k[i+4] - k[i+2]), multiply(P[i+1], k[i+2] - k[i+1]) ), k[i+4] - k[i+1]);
                    
                    //q0
                    var q_01 = (k[i+3] - k[i+2]) / (k[i+3] - k[i+1]);
                    var q_02 = divide( sum( multiply(P[i-1],k[i+3] - k[i+2]), multiply(P[i], k[i+2] - k[i])), k[i+3] - k[i]);
                    var q_03 = multiply(q1, ( k[i+2] - k[i+1])/ (k[i+3] - k[i+1]) );
                    var q0 = sum(multiply(q_02, q_01), q_03);
                    
                    //q2
                    var q2 = divide( sum( multiply(P[i], k[i+4] - k[i+3]), multiply(P[i+1], k[i+3] - k[i+1]) ), k[i+4] - k[i+1] );
                    
                    //q3
                    var q_31 = (k[i+3] - k[i+2]) / (k[i+4] - k[i+2]);
                    var q_32 = divide( sum( multiply(P[i+1], k[i+5] - k[i+3]), multiply(P[i+2], k[i+3] - k[i+2]) ) , k[i+5] - k[i+2]);
                    var q_33 = multiply(q2, (k[i+4] - k[i+3])/(k[i+4] - k[i+2]) );
                    var q3 = sum(multiply(q_32, q_31), q_33);                    
                    
                    sol.push([q0, q1, q2, q3]);
                }
                
                return sol;
            }
            
            function paint_point(ctx, color,  point){
                //return;
                ctx.save();
                switch(color){
                    case 'red':
                        ctx.strokeStyle = "rgb(200, 0,0)";
                        ctx.strokeRect(point[0]- 3 , point[1] - 3, 6, 6);
                        break;
                        
                    case 'black':
                        ctx.strokeStyle = "rgb(0, 0,0)";
                        ctx.strokeRect(point[0]- 1 , point[1] - 1, 2, 2);
                        break;
                        
                    case 'green':
                        ctx.strokeStyle = "rgb(0, 200,0)";
                        ctx.strokeRect(point[0]- 2 , point[1] - 2, 4, 4);
                        break;
                }                
                ctx.restore();
            }
            
            function paint_points(ctx, points, color){
                ctx.save();
                //controll points
                for(var i=0;i<points.length; i++){
                    paint_point(ctx, color, points[i]);
                }
                ctx.restore();
            }
            
            function paint_curve(ctx, points, step){
                ctx.save();
                //curve points
                var pts = sample(points, step);
                
//                for(var i=0;i<pts.length; i++){
//                    paint_point(ctx, "black", pts[i]);
//                }
                
                //line
                ctx.moveTo(pts[0][0], pts[0][1]);
                for(var i=1;i<pts.length; i++){
                    ctx.lineTo(pts[i][0], pts[i][1]);
                }
                ctx.stroke();
                ctx.restore();
            }
            
            function init(){
                var ctx = document.getElementById("pinza").getContext("2d");
               
                
                paint_points(ctx, s2_6, "red");                
                
                //paint_curve(ctx, s2_6, 0.01);
                
                var fragments = sample(s2_6);
                alert("Nr of quad curves " +  fragments.length);
                for(var f=0;f<fragments.length; f++){
                    var fragment = fragments[f];
                    ctx.moveTo(fragment[0][0], fragment[0][1]);
                    ctx.bezierCurveTo(fragment[1][0], fragment[1][1], fragment[2][0], fragment[2][1], fragment[3][0], fragment[3][1]);
                }
                ctx.stroke();
            }
            
            function sum(p1, p2){
                return [p1[0] + p2[0], p1[1] + p2[1]];
            }
            
            function minus(p1, p2){
                return [p1[0] - p2[0], p1[1] - p2[1]];
            }
            
            function divide(p, nr){
                if(nr == 0){ 
                    throw "Division by zero not allowed (yet :) " + this.callee ;
                }
                return [p[0]/nr, p[1]/nr];
            }
            
            function multiply(p, nr){
                return [p[0]*nr, p[1]*nr];
            }
        </script>
    </head>
    <body onload="init()">
        <canvas style="border: 1px solid gray;" id="pinza" width="1200" height="1200"></canvas>
    </body>
</html>
